﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.IO;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Reflection;
using Srvtools;
using System.Collections;
using System.Diagnostics;
using System.Text;
using System.Xml;
using System.Threading;
using System.Data;

namespace SingleSignOn
{
    public partial class frmSingleSignOn : InfoForm
    {
        private SYS_LANGUAGE language;

        public frmSingleSignOn()
        {
            language = CliSysMegLag.GetClientLanguage();
            InitializeComponent();
        }

        private string[] UserMessage;
        private string PackageMessage;
        private String flag = "F";
        public frmSingleSignOn(string userMessage, string packageMessage)
        {
            UserMessage = userMessage.Split(';');
            PackageMessage = packageMessage;
            language = CliSysMegLag.GetClientLanguage();
            InitializeComponent();
        }

        public frmSingleSignOn(string userMessage, string packageMessage, String f)
        {
            UserMessage = userMessage.Split(';');
            PackageMessage = packageMessage;
            language = CliSysMegLag.GetClientLanguage();
            flag = f;
            InitializeComponent();

        }

        private void SingleSignOn_Load(object sender, EventArgs e)
        {
            if (UserMessage != null)
            {
                CliUtils.fLoginUser = UserMessage[0];
                CliUtils.fLoginPassword = UserMessage[1];
                CliUtils.fLoginDB = UserMessage[2];
                CliUtils.fCurrentProject = UserMessage[3];
                if (flag != "W")
                {
                    string sParam = CliUtils.fLoginUser + ':' + CliUtils.fLoginPassword + ':' + CliUtils.fLoginDB + ":0";
                    object[] myRet = CliUtils.CallMethod("GLModule", "CheckUser", new object[] { (object)sParam });
                    if (myRet[1] == null || myRet[1] == DBNull.Value || myRet[1].ToString().Length == 0)
                        MessageBox.Show("User or Password is error.");
                }

                string[] packages = PackageMessage.Split(';');
                string PackageName = packages[0];
                string FormName = packages[1];
                string ss;

                if (flag != "W")
                    if (!checkPurview(PackageName)) Environment.Exit(0);

                ss = Application.StartupPath + "\\" + CliUtils.fCurrentProject + "\\";
                string strPackage = ss + PackageName + ".dll";
                Assembly a = null;
                bool bLoaded = DllContainer.DllLoaded(strPackage);

                if (!bLoaded || !File.Exists(strPackage)) CheckAndDownLoad(strPackage, PackageName + ".dll");
                try
                {
                    a = Assembly.LoadFrom(strPackage);
                }
                finally
                {
                    if (!bLoaded) DllContainer.AddDll(strPackage);
                }

                Type myType = a.GetType(PackageName + "." + FormName);

                if (myType != null)
                {
                    object obj = Activator.CreateInstance(myType);
                    ((IInfoForm)obj).SetPackageForm(PackageName, FormName);
                    ((InfoForm)obj).WindowState = FormWindowState.Normal;
                    ((InfoForm)obj).Select();
                    ((InfoForm)obj).StartPosition = FormStartPosition.CenterScreen;
                    ((Form)obj).FormClosed += InternalFormClosed;
                    ((InfoForm)obj).ShowDialog(this);
                }
            }
        }

        private void CheckAndDownLoad(string sFullPath, string sDll)
        {
            object[] oRet = null;
            DateTime d = File.GetLastWriteTime(sFullPath);//取得最后时间

            try
            {
                oRet = CliUtils.CallMethod("GLModule", "CheckAndDownLoad", new object[] { CliUtils.fCurrentProject, sDll, d });
            }
            finally
            {
            }

            if (null != oRet && ((int)oRet[0] == 0) && ((int)oRet[1] == 0))
            {
                byte[] bs = (byte[])oRet[3];
                DateTime ds = (DateTime)oRet[2];
                string sPath = Path.GetDirectoryName(sFullPath);
                if (!Directory.Exists(sPath))
                    Directory.CreateDirectory(sPath);
                File.WriteAllBytes(sFullPath, bs);
                File.SetLastAccessTime(sFullPath, ds);
            }
        }

        private bool checkPurview(string packageName)
        {
            //object[] LoginUser = new object[1];
            //LoginUser[0] = CliUtils.fLoginUser;
            object[] strParam = new object[2];
            strParam[0] = CliUtils.fCurrentProject;
            strParam[1] = "F";
            object[] myRet = CliUtils.CallMethod("GLModule", "FetchMenus", strParam);
            DataSet menuDataSet = new DataSet();
            if ((null != myRet) && (0 == (int)myRet[0]))
            {
                menuDataSet = (DataSet)(myRet[1]);
            }
            //string strCaption = SetMenuLanguage();
            bool flag = false;
            for (int i = 0; i < menuDataSet.Tables[0].Rows.Count; i++)
                if (menuDataSet.Tables[0].Rows[i]["package"].ToString() != "")
                {
                    if (menuDataSet.Tables[0].Rows[i]["package"].ToString() == packageName)
                    { flag = true; break; }
                }
                else
                {
                    if (menuDataSet.Tables[0].Rows[i]["caption"].ToString() == packageName)
                    { flag = true; break; }
                }
            if (!flag)
            {
                MessageBox.Show("You've nerver got the purview to open form " + packageName + "!");
                return false;
            }
            return true;
        }

        private string SetMenuLanguage()
        {
            string strCaption = "";
            switch (Program.GetClientLanguage())
            {
                case SYS_LANGUAGE.ENG:
                    strCaption = "caption0";
                    break;
                case SYS_LANGUAGE.TRA:
                    strCaption = "caption1";
                    break;
                case SYS_LANGUAGE.SIM:
                    strCaption = "caption2";
                    break;
                case SYS_LANGUAGE.HKG:
                    strCaption = "caption3";
                    break;
                case SYS_LANGUAGE.JPN:
                    strCaption = "caption4";
                    break;
                case SYS_LANGUAGE.LAN1:
                    strCaption = "caption5";
                    break;
                case SYS_LANGUAGE.LAN2:
                    strCaption = "caption6";
                    break;
                case SYS_LANGUAGE.LAN3:
                    strCaption = "caption7";
                    break;
            }
            return strCaption;
        }

        private void InternalFormClosed(object sender, FormClosedEventArgs e)
        {
            if (flag != "W")
            {
                CliUtils.CallMethod("GLModule", "LogOut", new object[] { (object)(UserMessage[0]) });
            }
            Environment.Exit(0);
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (flag != "W")
            {
                CliUtils.CallMethod("GLModule", "LogOut", new object[] { (object)(UserMessage[0]) });
            }
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        static class Program
        {
            ///<summary>
            ///The main entry point for the application.
            ///</summary>
            [STAThread]
            static void Main(string[] args)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                CliUtils.fClientLang = GetClientLanguage();
                String s;
                s = Application.StartupPath + "\\";
                //RemotingConfiguration.Configure(s + "SingleSignOn.exe.config", true);

                if (!File.Exists(s + "SingleSignOn.exe.config"))
                {
                    SetRegistry(Application.StartupPath);

                    frmSetServerIP fss = new frmSetServerIP();
                    fss.ShowDialog();
                    return;
                }

                CliUtils.LoadLoginServiceConfig(s + "SingleSignOn.exe.config");
                
                string message = "";
                bool rtn = CliUtils.Register(ref message);
                object[] myRet = new object[1];
                if (rtn)
                {
                    object[] param = new object[2];
                    param[0] = Environment.MachineName;
                    param[1] = Application.StartupPath;
                    myRet =  CliUtils.CallMethod("GLModule", "SetSingleSignOnPath", param);

                    SetRegistry(Application.StartupPath);
                }
                else
                {
                    SetRegistry(Application.StartupPath);
                    
                    frmSetServerIP fss = new frmSetServerIP();
                    fss.ShowDialog();

                    return;
                }

                //            LoginService loginService = new LoginService(); // Remoting object

                //BeginObtainService:
                //            // Obtain service from the master server
                //            string serverIP = "";

                //            try
                //            {
                //                serverIP = loginService.GetServerIP();

                //            }
                //            catch (Exception err)
                //            {
                //                if ((string.Compare(err.Message.ToLower(), "unable to connect to the remote server") == 0) &&
                //                    CliUtils.PassByEEPListener())
                //                {
                //                    try
                //                    {
                //                        CliUtils.EEPListenerService.StartupEEPNetServer();
                //                    }
                //                    catch (Exception E)
                //                    {
                //                        MessageBox.Show(E.Message);
                //                        //this.Close();
                //                        return;
                //                    }
                //                    goto BeginObtainService;
                //                }
                //                else
                //                {
                //                    MessageBox.Show(err.Message);
                //                    //this.Close();
                //                    return;
                //                }
                //            }

                //            if (serverIP == null || serverIP.Trim() == "")
                //            {
                //                MessageBox.Show("Can not login due to busy service");
                //                //this.Close();
                //                return;
                //            }

                //            // Try to connect to server, reobtain service from the master server if failed
                //            try
                //            {
                //                EEPRemoteModule module = Activator.GetObject(typeof(EEPRemoteModule),
                //                    string.Format("http://{0}:8989/InfoRemoteModule.rem", serverIP)) as EEPRemoteModule;
                //                module.ToString();
                //            }
                //            catch
                //            {
                //                loginService.DeRegisterRemoteServer(serverIP);
                //                goto BeginObtainService;
                //            }

                //            // Register EEPRemoteModule on the server
                //            WellKnownClientTypeEntry clientEntry = new WellKnownClientTypeEntry(typeof(EEPRemoteModule),
                //                string.Format("http://{0}:8989/InfoRemoteModule.rem", serverIP));
                //            RemotingConfiguration.RegisterWellKnownClientType(clientEntry);

                // End Add
                if (args.Length > 0)
                {
                    if (args[0].StartsWith("websinglesignon:", StringComparison.CurrentCultureIgnoreCase))
                    {
                        args[0] = args[0].Replace("websinglesignon:", "");
                    }

                    string[] temp = args[0].Split('!');
                    string userMessage = temp[0];
                    string packageMessage = temp[1];
                    string f = "";
                    if (temp.Length > 2)
                        f = temp[2];
                    //Mutex m = new Mutex(false, userMessage);
                    Application.Run(new frmSingleSignOn(userMessage, packageMessage, f));
                }
                else
                {
                    if (myRet[0] != null && Convert.ToInt32(myRet[0]) == 0)
                        MessageBox.Show("Install is suceess.");
                    Environment.Exit(0);

                    //Application.Run(new frmSingleSignOn());
                }
            }

            static public SYS_LANGUAGE GetClientLanguage()
            {
                uint dwlang = GetThreadLocale();
                ushort wlang = (ushort)dwlang;
                ushort wprilangid = (ushort)(wlang & 0x3FF);
                ushort wsublangid = (ushort)(wlang >> 10);

                if (0x09 == wprilangid)
                    return SYS_LANGUAGE.ENG;
                else if (0x04 == wprilangid)
                {
                    if (0x01 == wsublangid)
                        return SYS_LANGUAGE.TRA;
                    else if (0x02 == wsublangid)
                        return SYS_LANGUAGE.SIM;
                    else if (0x03 == wsublangid)
                        return SYS_LANGUAGE.HKG;
                    else
                        return SYS_LANGUAGE.TRA;
                }
                else if (0x11 == wprilangid)
                    return SYS_LANGUAGE.JPN;
                else
                    return SYS_LANGUAGE.ENG;
            }

            [DllImport("KERNEL32.DLL", EntryPoint = "GetThreadLocale", SetLastError = true,
                CharSet = CharSet.Unicode, ExactSpelling = true,
                CallingConvention = CallingConvention.StdCall)]
            public static extern uint GetThreadLocale();

            private static void SetRegistry(String path)
            {
                RegistryKey rk = Registry.ClassesRoot.OpenSubKey("WebSingleSignOn", true);
                if (rk == null)
                {
                    rk = Registry.ClassesRoot.CreateSubKey("WebSingleSignOn", RegistryKeyPermissionCheck.ReadWriteSubTree);
                    rk.SetValue("", "URL: WebSingleSignOn Protocol");
                    rk.SetValue("URL Protocol", "");

                    rk = rk.CreateSubKey("shell", RegistryKeyPermissionCheck.ReadWriteSubTree);
                    rk.SetValue("", "open");

                    rk = rk.CreateSubKey("open", RegistryKeyPermissionCheck.ReadWriteSubTree);
                    rk.SetValue("", "open");

                    rk = rk.CreateSubKey("Command", RegistryKeyPermissionCheck.ReadWriteSubTree);
                    rk.SetValue("", "\"" + path + "\\SingleSignOn.exe\" \"%1\"");

                    rk.Close();
                }
                else
                {
                    rk = Registry.ClassesRoot.OpenSubKey("WebSingleSignOn\\shell\\open\\Command", RegistryKeyPermissionCheck.ReadWriteSubTree);
                    rk.SetValue("", "\"" + path + "\\SingleSignOn.exe\" \"%1\"");
                }
            }
        }

        public static class DllContainer
        {
            public static ArrayList NameList = new ArrayList();

            public static bool DllLoaded(string sName)
            {
                bool bRet = false;
                for (int i = 0; i < NameList.Count; i++)
                {
                    if (((string)NameList[i]).Trim().ToUpper().Equals(sName.Trim().ToUpper()))
                    {
                        bRet = true;
                        break;
                    }
                }

                return bRet;
            }

            public static void AddDll(string sName)
            {
                NameList.Add(sName);
            }
        }
    }
}